package com.gxjtkyy.datadistributer.writer.rdbms.util.oracle;

import com.google.common.base.Preconditions;
import com.gxjtkyy.datadistributer.writer.rdbms.util.SqlTemplate;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import lombok.NonNull;
import org.apache.commons.lang3.StringUtils;

public class OracleSqlTemplate implements SqlTemplate {
   public String getCountSql(String schema, @NonNull String table, @NonNull List<String> pkColumns) {
      if (table == null) {
         throw new NullPointerException("table is marked non-null but is null");
      } else if (pkColumns == null) {
         throw new NullPointerException("pkColumns is marked non-null but is null");
      } else {
         Preconditions.checkArgument(!pkColumns.isEmpty());
         String template = "select count(*) from %s where %s";
         String fullTableName = this.getFullTableName(schema, table);
         String wherePart = (String)pkColumns.stream().map((pkColumn) -> {
            return pkColumn + "=?";
         }).collect(Collectors.joining(" AND "));
         return String.format(template, fullTableName, wherePart);
      }
   }

   public String getSelectSql(String schema, @NonNull String table, @NonNull List<String> pkColumns, @NonNull List<String> columns) {
      if (table == null) {
         throw new NullPointerException("table is marked non-null but is null");
      } else if (pkColumns == null) {
         throw new NullPointerException("pkColumns is marked non-null but is null");
      } else if (columns == null) {
         throw new NullPointerException("columns is marked non-null but is null");
      } else {
         Preconditions.checkArgument(!pkColumns.isEmpty());
         String template = "select %s from %s";
         String selectPart = (String)Stream.concat(pkColumns.stream(), columns.stream()).collect(Collectors.joining(","));
         String fullTableName = this.getFullTableName(schema, table);
         return String.format(template, selectPart, fullTableName);
      }
   }

   public String getInsertSql(String schema, @NonNull String table, @NonNull List<String> pkColumns, @NonNull List<String> columns, Map<String, String> columnMap) {
      if (table == null) {
         throw new NullPointerException("table is marked non-null but is null");
      } else if (pkColumns == null) {
         throw new NullPointerException("pkColumns is marked non-null but is null");
      } else if (columns == null) {
         throw new NullPointerException("columns is marked non-null but is null");
      } else {
         Preconditions.checkArgument(!columns.isEmpty());
         String template = "insert into %s(%s) values(%s)";
         String fullTableName = this.getFullTableName(schema, table);
         List<String> allColumns = (List)Stream.concat(pkColumns.stream(), columns.stream()).collect(Collectors.toList());
         String columnPart = String.join(",", allColumns);
         String valuePart = (String)Stream.generate(() -> {
            return "?";
         }).limit((long)allColumns.size()).collect(Collectors.joining(","));
         return String.format(template, fullTableName, columnPart, valuePart);
      }
   }

   public String getUpdateSql(String schema, @NonNull String table, @NonNull List<String> pkColumns, @NonNull List<String> columns) {
      if (table == null) {
         throw new NullPointerException("table is marked non-null but is null");
      } else if (pkColumns == null) {
         throw new NullPointerException("pkColumns is marked non-null but is null");
      } else if (columns == null) {
         throw new NullPointerException("columns is marked non-null but is null");
      } else {
         Preconditions.checkArgument(!pkColumns.isEmpty());
         Preconditions.checkArgument(!columns.isEmpty());
         String template = "update %s set %s where %s";
         String fullTableName = this.getFullTableName(schema, table);
         String updatePart = (String)columns.stream().map((column) -> {
            return column + "=?";
         }).collect(Collectors.joining(","));
         String pkPart = (String)pkColumns.stream().map((column) -> {
            return column + "=?";
         }).collect(Collectors.joining(" and "));
         return String.format(template, fullTableName, updatePart, pkPart);
      }
   }

   public String getDeleteSql(String schema, @NonNull String table, @NonNull List<String> pkColumns) {
      if (table == null) {
         throw new NullPointerException("table is marked non-null but is null");
      } else if (pkColumns == null) {
         throw new NullPointerException("pkColumns is marked non-null but is null");
      } else {
         Preconditions.checkArgument(!pkColumns.isEmpty());
         String template = "delete from %s where %s";
         String fullTableName = this.getFullTableName(schema, table);
         String pkPart = (String)pkColumns.stream().map((pkColumn) -> {
            return pkColumn + "=?";
         }).collect(Collectors.joining(" and "));
         return String.format(template, fullTableName, pkPart);
      }
   }

   public String getMergeSql(String schema, @NonNull String table, @NonNull List<String> pkColumns, @NonNull List<String> columns, @NonNull List<String> updateColumns,
                             @NonNull Map<String, String> comparableColumns, boolean insertable, boolean updateTable, Map<String, String> columnMap) {
      if (table == null) {
         throw new NullPointerException("table is marked non-null but is null");
      } else if (pkColumns == null) {
         throw new NullPointerException("pkColumns is marked non-null but is null");
      } else if (columns == null) {
         throw new NullPointerException("columns is marked non-null but is null");
      } else if (updateColumns == null) {
         throw new NullPointerException("updateColumns is marked non-null but is null");
      } else if (comparableColumns == null) {
         throw new NullPointerException("comparableColumns is marked non-null but is null");
      } else {
         String template = "merge into %s t1 using (select %s from dual) t2 on (%s)";
         String fullTableName = this.getFullTableName(schema, table);
         List<String> allColumns = (List)Stream.concat(pkColumns.stream(), columns.stream()).collect(Collectors.toList());
         String usingPart = (String)allColumns.stream().map((column) -> {
            return "? as " + column;
         }).collect(Collectors.joining(","));
         String pkPart = (String)pkColumns.stream().map((pkColumn) -> {
            return "t1." + pkColumn + "=t2." + pkColumn;
         }).collect(Collectors.joining(" and "));
         String sql = String.format(template, fullTableName, usingPart, pkPart);
         String template3;
         String updatePart;
         String part3;
         String wherePart;
         if (insertable) {
            template3 = " when not matched then insert(%s) values (%s)";
            updatePart = (String)allColumns.stream().map((column) -> {
               return "t1." + column;
            }).collect(Collectors.joining(","));
            part3 = (String)allColumns.stream().map((column) -> {
               return "t2." + column;
            }).collect(Collectors.joining(","));
            wherePart = String.format(template3, updatePart, part3);
            sql = sql + wherePart;
         }

         if (updateTable && !updateColumns.isEmpty()) {
            template3 = " when matched then update set %s";
            updatePart = (String)updateColumns.stream().map((column) -> {
               return "t1." + column + "=t2." + column;
            }).collect(Collectors.joining(","));
            part3 = String.format(template3, updatePart);
            if (!comparableColumns.isEmpty()) {
               wherePart = (String)comparableColumns.entrySet().stream().map((column) -> {
                  String var10000 = (String)column.getKey();
                  return "t1." + var10000 + " " + (String)column.getValue() + " t2." + (String)column.getKey();
               }).collect(Collectors.joining(" and "));
               part3 = part3 + " where " + wherePart;
            }

            sql = sql + part3;
         }

         return sql;
      }
   }

   @Override
   public String getSaveOrUpdateSql(String schema, String table, List<String> pkColumns, List<String> columns, List<String> updateColumns, Map<String, String> comparableColumns, boolean insertable, boolean updateTable, Map<String, String> columnMa) {
      return null;
   }

   private String getFullTableName(String schema, @NonNull String table) {
      if (table == null) {
         throw new NullPointerException("table is marked non-null but is null");
      } else {
         return StringUtils.isBlank(schema) ? table : schema + "." + table;
      }
   }
}
